﻿Imports System.Net.Sockets
Imports System.Net

Public Class ISC

    Public Shared clients As IList = New Collections.ArrayList
    Public Shared checkRead As IList = New Collections.ArrayList
    Public Shared checkError As IList = New Collections.ArrayList
    Public Shared channels As IList = New Collections.ArrayList
    Public Shared numClients As Integer = 0
    Public Shared listener As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

    Public Shared Sub start()
        Try
            listener.Bind(New IPEndPoint(IPAddress.Parse(Config.ISCIP), Config.ISCClusterServerPort))
            listener.Listen(100)
            listener.Blocking = False
            log.log(LogType.MSG_INFO, "ISC ready on port " & String.Concat(Config.ISCClusterServerPort))
        Catch
        End Try
        Dim ISCThread As New Threading.Thread(AddressOf ISC.ISCThread)
        ISCThread.Start()
    End Sub

    Public Shared Sub ISCThread()
        Do While True
            Try
                checkRead.Clear()
                checkError.Clear()
                For Each obj As Object In clients
                    Dim ISCHandler As ISCHandler = obj
                    checkRead.Add(ISCHandler.workSocket)
                    checkError.Add(ISCHandler.workSocket)
                Next
                checkRead.Add(listener)
                checkError.Add(listener)
                Socket.Select(checkRead, Nothing, checkError, 1000)
                For Each obj As Object In clients
                    Dim ISCHandler As ISCHandler = obj
                    If (checkRead.Contains(ISCHandler.workSocket)) Then
                        If (ISCHandler.handle() <> True) Then
                            If (channels.Contains(ISCHandler.place)) Then
                                channels.Remove(ISCHandler.place)
                                log.log(LogType.MSG_INFO, "Channel Disconnected")
                            End If
                            ISCHandler.workSocket.Close()
                            clients.Remove(ISCHandler)
                            LoginServer.updateCluster()
                            Continue Do
                        End If
                    End If
                    If (checkError.Contains(ISCHandler.workSocket)) Then
                        If (channels.Contains(ISCHandler.place)) Then
                            channels.Remove(ISCHandler.place)
                            log.log(LogType.MSG_INFO, "Channel Disconnected")
                        End If
                        ISCHandler.workSocket.Close()
                        clients.Remove(ISCHandler)
                        LoginServer.updateCluster()
                        Continue Do
                    End If
                Next

                If (checkRead.Contains(listener)) Then
                    If (handle(listener) <> True) Then
                        log.log(LogType.MSG_ERROR, "Error in ISC's main socket.")
                        listener.Close()
                        Exit Do
                    End If
                End If
                If (checkError.Contains(listener)) Then
                    listener.Close()
                    Exit Do
                End If
            Catch
            End Try
        Loop
    End Sub

    Public Shared Function handle(ByVal socket As Socket) As Boolean
        Try
            Dim client As Socket = socket.Accept()
            Dim handler As New ISCHandler(client)
            clients.Add(handler)
            checkRead.Add(client)
            checkError.Add(client)
            numClients += 1
            Return True
        Catch ex As SocketException
        End Try
    End Function

End Class